home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 May: Tool Chest / Developer CD Series May 1996 (Tool Chest) (Apple Computer) (1996).iso / Sample Code / AppsToGo / Kibitz / AppleEvents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-09-22  |  8.9 KB  |  355 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        appleevents.c
  5. ** Written by:  Keith Rollin
  6. **
  7. ** Copyright © 1990-1994 Apple Computer, Inc.
  8. ** All rights reserved.
  9. **
  10. ** This code is completely based on the great work done by Keith Rollin.
  11. ** All I did was to add more comments than _anybody_ would want, make some
  12. ** things a little more general, and to set the code up so the the custom
  13. ** events are handled in a separate file. */
  14.  
  15.  
  16.  
  17. /*****************************************************************************/
  18.  
  19.  
  20.  
  21. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  22. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  23. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  24.  
  25. #ifndef __AEUTILS__
  26. #include <AEUtils.h>
  27. #endif
  28.  
  29. #ifndef __GESTALTEQU__
  30. #include <GestaltEqu.h>
  31. #endif
  32.  
  33. #ifndef __UTILITIES__
  34. #include <Utilities.h>
  35. #endif
  36.  
  37.  
  38.  
  39. /*****************************************************************************/
  40.  
  41.  
  42.  
  43. #define rErrorAlert 129
  44. #define kTimeOutInTicks (60 * 30)    /* 30 second timeout. */
  45.  
  46.  
  47.  
  48. /*****************************************************************************/
  49.  
  50.  
  51.  
  52. struct triplets{
  53.     AEEventClass        theEventClass;
  54.     AEEventID            theEventID;
  55.     ProcPtr                theHandler;
  56.     AEEventHandlerUPP    theUPP;
  57. };
  58. typedef struct triplets triplets;
  59. static triplets keywordsToInstall[] = {
  60.     { kCoreEventClass,        kAEOpenApplication,        (ProcPtr)KibitzAEOpenApplication,    nil },
  61.     { kCoreEventClass,        kAEOpenDocuments,        (ProcPtr)KibitzAEOpenDocuments,        nil },
  62.     { kCoreEventClass,        kAEPrintDocuments,        (ProcPtr)KibitzAEPrintDocuments,    nil },
  63.     { kCoreEventClass,        kAEQuitApplication,        (ProcPtr)KibitzAEQuitApplication,    nil }
  64.         /* The above are the four required AppleEvents. */
  65. };
  66.  
  67. Boolean        gHasAppleEvents = false;
  68. Boolean        gHasPPCToolbox  = false;
  69.  
  70.  
  71.  
  72. /*****************************************************************************/
  73.  
  74.  
  75.  
  76. extern Boolean    gQuitApplication;
  77. extern Cursor    *gCurrentCursor;
  78. extern short    gPrintPage;
  79.  
  80.  
  81.  
  82. /*****************************************************************************/
  83. /*****************************************************************************/
  84.  
  85. #ifdef applec
  86. #pragma segment AppleEvents
  87. #endif
  88.  
  89. /*****************************************************************************/
  90. /*****************************************************************************/
  91.  
  92.  
  93.  
  94. /* InitAppleEvents
  95. **
  96. ** Intialize our AppleEvent dispatcher table.  For every triplet of entries in
  97. ** keywordsToInstall, we make a call to AEInstallEventHandler(). */
  98.  
  99. void    InitAppleEvents(void)
  100. {
  101.     OSErr    err;
  102.     long    result;
  103.     short    i;
  104.  
  105.     gHasPPCToolbox  = (Gestalt(gestaltPPCToolboxAttr, &result) ? false : result != 0);
  106.     gHasAppleEvents = (Gestalt(gestaltAppleEventsAttr, &result) ? false : result != 0);
  107.  
  108.     if (gHasAppleEvents) {
  109.         for (i = 0; i < (sizeof(keywordsToInstall) / sizeof(triplets)); ++i) {
  110.  
  111.             if (!keywordsToInstall[i].theUPP)
  112.                 keywordsToInstall[i].theUPP = NewAEEventHandlerProc(keywordsToInstall[i].theHandler);
  113.  
  114.             err = AEInstallEventHandler(
  115.                 keywordsToInstall[i].theEventClass,    /* What class to install.  */
  116.                 keywordsToInstall[i].theEventID,    /* Keywords to install.    */
  117.                 keywordsToInstall[i].theUPP,        /* The AppleEvent handler. */
  118.                 0L,                                    /* Unused refcon.           */
  119.                 false                                /* Only for our app.       */
  120.             );
  121.  
  122.             if (err) {
  123.                 Alert(rErrorAlert, gAlertFilterUPP);
  124.                 return;
  125.             }
  126.         }
  127.     }
  128. }
  129.  
  130.  
  131.  
  132. /*****************************************************************************/
  133. /*****************************************************************************/
  134.  
  135.  
  136.  
  137. pascal OSErr    KibitzAEOpenApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  138. {
  139. #ifndef __MWERKS__
  140. #pragma unused (message, refcon)
  141. #endif
  142.  
  143.     OSErr        err;
  144.  
  145.     err = noErr;
  146.  
  147.     gCurrentCursor = nil;
  148.         /* Force re-calc of cursor region and cursor to use. */
  149.  
  150.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  151.         reply,                    /* The AppleEvent.              */
  152.         keyReplyErr,            /* AEKeyword                 */
  153.         typeShortInteger,        /* Desired type.             */
  154.         (Ptr)&err,                /* Pointer to area for data. */ 
  155.         sizeof(short)            /* Size of data area.         */
  156.     );
  157.  
  158.     return(err);
  159. }
  160.  
  161.  
  162.  
  163. /*****************************************************************************/
  164.  
  165.  
  166.  
  167. pascal OSErr    KibitzAEOpenDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  168. {
  169. #ifndef __MWERKS__
  170. #pragma unused (refcon)
  171. #endif
  172.  
  173.     OSErr        err;
  174.  
  175.     gCurrentCursor = nil;
  176.         /* Force re-calc of cursor region and cursor to use. */
  177.  
  178.     err = OpenDocEventHandler(message, reply, 0);
  179.  
  180.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  181.         reply,                    /* The AppleEvent.              */
  182.         keyReplyErr,            /* AEKeyword                 */
  183.         typeShortInteger,        /* Desired type.             */
  184.         (Ptr)&err,                /* Pointer to area for data. */ 
  185.         sizeof(short)            /* Size of data area.         */
  186.     );
  187.  
  188.     return(err);
  189. }
  190.  
  191.  
  192.  
  193. /*****************************************************************************/
  194.  
  195.  
  196.  
  197. pascal OSErr    KibitzAEPrintDocuments(AppleEvent *message, AppleEvent *reply, long refcon)
  198. {
  199. #ifndef __MWERKS__
  200. #pragma unused (refcon)
  201. #endif
  202.  
  203.     OSErr        err;
  204.     short        openMode;
  205.  
  206.     DoSetCursor(&qd.arrow);
  207.  
  208.     openMode = 1;
  209.     if (!AEInteractWithUser(kTimeOutInTicks, nil, nil)) ++openMode;
  210.  
  211.     err = OpenDocEventHandler(message, reply, openMode);
  212.  
  213.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  214.         reply,                    /* The AppleEvent.              */
  215.         keyReplyErr,            /* AEKeyword                 */
  216.         typeShortInteger,        /* Desired type.             */
  217.         (Ptr)&err,                /* Pointer to area for data. */ 
  218.         sizeof(short)            /* Size of data area.         */
  219.     );
  220.  
  221.     return(err);
  222. }
  223.  
  224.  
  225.  
  226. /*****************************************************************************/
  227.  
  228.  
  229.  
  230. pascal OSErr    KibitzAEQuitApplication(AppleEvent *message, AppleEvent *reply, long refcon)
  231. {
  232. #ifndef __MWERKS__
  233. #pragma unused (message, refcon)
  234. #endif
  235.  
  236.     OSErr    err;
  237.  
  238.     gCurrentCursor = nil;
  239.         /* Force re-calc of cursor region and cursor to use. */
  240.  
  241.     if (CloseAllWindows()) {
  242.         gQuitApplication = true;
  243.         err = noErr;
  244.     }
  245.     else err = errAEEventNotHandled;
  246.  
  247.     AEPutParamPtr(                /* RETURN REPLY ERROR, EVEN IF NONE... */
  248.         reply,                    /* The AppleEvent.              */
  249.         keyReplyErr,            /* AEKeyword                 */
  250.         typeShortInteger,        /* Desired type.             */
  251.         (Ptr)&err,                /* Pointer to area for data. */ 
  252.         sizeof(short)            /* Size of data area.         */
  253.     );
  254.  
  255.     return(noErr);
  256. }
  257.  
  258.  
  259.  
  260. /*****************************************************************************/
  261.  
  262.  
  263.  
  264. /* OpenDocEventHandler
  265. **
  266. ** Called when we recieve an AppleEvent with an ID of "kAEOpenDocuments".
  267. ** This routine gets the direct parameter, parses it up into little FSSpecs,
  268. ** and opens each indicated file.  It also shows the technique to be used in
  269. ** determining if you are doing everything the AppleEvent record is telling
  270. ** you.  Parameters can be divided up into two groups: required and optional.
  271. ** Before executing an event, you must make sure that you've read all the
  272. ** required events.  This is done by making an "any more?" call to the
  273. ** AppleEvent manager. */
  274.  
  275. OSErr    OpenDocEventHandler(AppleEvent *message, AppleEvent *reply, short mode)
  276. {
  277. #ifndef __MWERKS__
  278. #pragma unused (reply)
  279. #endif
  280.  
  281.     OSErr        err;
  282.     OSErr        err2;
  283.     AEDesc        theDesc;
  284.     FSSpec        theFSS;
  285.     short        loop;
  286.     long        numFilesToOpen;
  287.     AEKeyword    ignoredKeyWord;
  288.     DescType    ignoredType;
  289.     Size        ignoredSize;
  290.     FileRecHndl    frHndl;
  291.     WindowPtr    docWindow;
  292.  
  293.     theDesc.dataHandle = nil;
  294.         /* Make sure disposing of the descriptors is okay in all cases.
  295.         ** This will not be necessary after 7.0b3, since the calls that
  296.         ** attempt to create the descriptors will nil automatically
  297.         ** upon failure. */
  298.  
  299.     err = AEGetParamDesc(message, keyDirectObject, typeAEList, &theDesc);
  300.     if (err)
  301.         return(err);
  302.  
  303.     if (!MissedAnyParameters(message)) {
  304.  
  305. /* Got all the parameters we need.  Now, go through the direct object,
  306. ** see what type it is, and parse it up. */
  307.  
  308.         err = AECountItems(&theDesc, &numFilesToOpen);
  309.         if (!err) {
  310.             /* We have numFilesToOpen that need opening, as either a window
  311.             ** or to be printed.  Go to it... */
  312.  
  313.             for (loop = 1; ((loop <= numFilesToOpen) && (!err)); ++loop) {
  314.                 err = AEGetNthPtr(        /* GET NEXT IN THE LIST...         */
  315.                     &theDesc,            /* List of file names.             */
  316.                     loop,                /* Item # in the list.             */
  317.                     typeFSS,            /* Item is of type FSSpec.         */
  318.                     &ignoredKeyWord,    /* Returned keyword -- we know.  */
  319.                     &ignoredType,        /* Returned type -- we know.     */
  320.                     (Ptr)&theFSS,        /* Where to put the FSSpec info. */
  321.                     sizeof(theFSS),        /* Size of the FSSpec info.         */
  322.                     &ignoredSize        /* Actual size -- we know.         */
  323.                 );
  324.                 if (err) break;
  325.  
  326.                 err = AppOpenDocument(&frHndl, &theFSS, fsRdWrPerm);
  327.                 if (err) break;
  328.  
  329.                 gPrintPage = mode;
  330.                     /* Open the window off-screen if we are printing. */
  331.                 err = AppNewWindow(frHndl, &docWindow, (WindowPtr)-1);
  332.                 if (err)
  333.                     AppDisposeDocument(frHndl);
  334.                 else {
  335.                     if (gPrintPage) {
  336.                         err  = AppPrintDocument(frHndl, (mode == 2), (loop == 1));
  337.                         mode = 1;
  338.                         AppDisposeDocument(frHndl);
  339.                         DisposeAnyWindow(docWindow);
  340.                     }
  341.                     else AppAutoLaunch(frHndl);
  342.                 }
  343.                 gPrintPage = 0;
  344.             }
  345.         }
  346.     }
  347.     AppPrintDocument(nil, false, false);    /* Clean up after printing, if we did any. */
  348.  
  349.     err2 = AEDisposeDesc(&theDesc);
  350.     return(err ? err : err2);
  351. }
  352.  
  353.  
  354.  
  355.